#include <QTimer>
#include <QDebug>
#include <QByteArray>
#include <QQmlComponent>
#include "SingleApplication.h"




void SingleApplication::_initStyle(void)
{
    QString style = QQuickStyle::name();
    if (!style.isEmpty()){
        settings.setValue("style", style);
    }
    else
        QQuickStyle::setStyle(settings.value("style").toString());
}


void SingleApplication::_initCommon()
{
    _initStyle();
    _initEngineOrViewer(false);
}

void SingleApplication::_initEngineOrViewer(bool data)
{
    isViewer = data;
    if(isViewer){
        viewer = new QQuickView();
        QObject::connect(viewer->engine(), SIGNAL(quit()), this, SLOT(quit()));
    }else{
        pEngine = new MEngine();
        QObject::connect(pEngine, SIGNAL(quit()), this, SLOT(quit()));
    }
}

int SingleApplication::_loadQMLFile()
{
    pEngine->addImportPath("qrc:/imports");
    pEngine->addImportPath("qrc:///");
    //pEngine->load(QStringLiteral("qrc:/main.qml"));
    component = new QQmlComponent(pEngine , QStringLiteral("qrc:/main.qml"));
    qDebug() << component->errors();
    if (pEngine->rootObjects().isEmpty())
        return -1;
    return 0;
}

QQmlContext *SingleApplication::getRootContext()
{
    return  isViewer? viewer->rootContext(): pEngine->rootContext();
}

QObject *SingleApplication::getRootObject(void)
{
    return component->create();
}


SingleApplication::SingleApplication(int &argc, char *argv[], const QString uniqueKey) : QApplication(argc, argv)
{
    sharedMemory.setKey(uniqueKey);
    if (sharedMemory.attach())
        _isRunning = true;
    else
    {
        _isRunning = false;
        // attach data to shared memory.
        QByteArray byteArray("0"); // default value to note that no message is available.
        if (!sharedMemory.create(byteArray.size()))
        {
            qDebug("Unable to create single instance.");
            return;
        }
        sharedMemory.lock();
        char *to = (char*)sharedMemory.data();
        const char *from = byteArray.data();
        memcpy(to, from, qMin(sharedMemory.size(), byteArray.size()));
        sharedMemory.unlock();

                // start checking for messages of other instances.
        QTimer *timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(checkForMessage()));
        timer->start(1000);
    }
}
void SingleApplication::log()
{
    qDebug("qt quit");
}
// public slots.
void SingleApplication::checkForMessage()
{
    sharedMemory.lock();
    QByteArray byteArray = QByteArray((char*)sharedMemory.constData(), sharedMemory.size());
    sharedMemory.unlock();
    if (byteArray.left(1) == "0")
        return;
    byteArray.remove(0, 1);
    byteArray = "0";
    sharedMemory.lock();
    char *to = (char*)sharedMemory.data();
    const char *from = byteArray.data();
    memcpy(to, from, qMin(sharedMemory.size(), byteArray.size()));
    sharedMemory.unlock();
}

bool SingleApplication::sendMessage(const QString &message)
{
    if (!_isRunning)
        return false;

    QByteArray byteArray("1");
    byteArray.append(message.toUtf8());
    sharedMemory.lock();
    char *to = (char*)sharedMemory.data();
    const char *from = byteArray.data();
    memcpy(to, from, qMin(sharedMemory.size(), byteArray.size()));
    sharedMemory.unlock();
    return true;
}

// public functions.
bool SingleApplication::isRunning()
{
    return _isRunning;
}
